package com.chennan.leading.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.integration.zookeeper.lock.ZookeeperLockRegistry;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * @author chennan
 * @createTime 2022年03月24日 15:00:00
 */
@Service
public class Testlock {

//    @Autowired
//    private RedisLockRegistry lockRegistry1;

    @Autowired
    private ZookeeperLockRegistry lockRegistry;

    // 使用场景1：如果获取不到锁，会等待一定时间再次获取（spring设置的获取频率是100毫秒），直至获取到为止
    public void testRedisLock(Long userId) {
        Lock lock = lockRegistry.obtain("user-service:save-userinfo:" + userId);
        lock.lock();
        try {
            System.out.println("testRedisLock 开始执行业务代码。。。。");
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("testRedisLock 结束执行业务代码。。。。");

            // 实际的业务处理代码...
        } finally {
            lock.unlock();
        }
    }

    // 使用场景2：如果tryLock()获取不到锁则返回false
    public void testRedisTryLock(Long userId) {
        Lock lock = lockRegistry.obtain("user-service:save-userinfo:" + userId);
        if (lock.tryLock()) {
            try {
                System.out.println("testRedisTryLock 执行业务代码。。。。");
                // 实际的业务处理代码...
            } finally {
                lock.unlock();
            }
        } else {
            System.out.println("testRedisTryLock not get lock");
            // 未获取到锁，实际的业务代码...
        }
    }

    // 使用场景3：使用带参数的tryLock，如果获取不到锁，在指定时间内会尝试多次获取（获取频率为100毫秒1次。比如：你指定时间段为500毫秒，则这500毫秒内每100毫秒获取一次直到成功或时间用尽）
    public void testRedisTryLockWithtimeLimit(Long userId) throws InterruptedException {
        Lock lock = lockRegistry.obtain("user-service:save-userinfo:" + userId);
        if (lock.tryLock(500, TimeUnit.MICROSECONDS)) {
            try {
                System.out.println("testRedisTryLockWithtimeLimit 执行业务代码。。。。");
                // 实际的业务处理代码...
            } finally {
                lock.unlock();
            }
        } else {
            System.out.println("testRedisTryLockWithtimeLimit not get lock");
            // 未获取到锁，实际的业务代码...

        }
    }

}
